#pragma once
#include "SLList.h"
#include <process.h>

template <typename T> class	SLList; 

template <typename T>
class SLLIter	
{
	friend class SLList<T>;

	typename SLList<T>::Node * cur;
	typename SLList<T>::Node * prev;
	SLList<T> * list;
public:
	///////////////////////////////////////////////////////////////////////////////
	// Function : Constructor
	// Parameters :	listToIterate - the list to iterate
	///////////////////////////////////////////////////////////////////////////////
	SLLIter(SLList<T>& listToIterate);
	SLLIter(const SLList<T>& listToIterate);

	///////////////////////////////////////////////////////////////////////////////
	// Function : begin
	// Notes : moves the iterator to the head of the list
	///////////////////////////////////////////////////////////////////////////////
	void begin();

	///////////////////////////////////////////////////////////////////////////////
	// Function : end
	// Notes : returns true if we are at the end of the list, false otherwise
	///////////////////////////////////////////////////////////////////////////////
	bool end() const;

	///////////////////////////////////////////////////////////////////////////////
	// Function : operator++
	// Notes : move the iterator forward one node
	///////////////////////////////////////////////////////////////////////////////
	SLLIter<T>& operator++();

	///////////////////////////////////////////////////////////////////////////////
	// Function : current
	// Notes : returns the item at the current iterator location
	///////////////////////////////////////////////////////////////////////////////
	T& current() const;

};

///////////////////////////////////////////////////////////////////////////////
// Function : Constructor
// Parameters :	listToIterate - the list to iterate
///////////////////////////////////////////////////////////////////////////////
template <typename T>
SLLIter<T>::SLLIter(SLList<T>& listToIterate) : prev(0), cur(listToIterate.head), list(&listToIterate)
{

}


template <typename T>
SLLIter<T>::SLLIter(const SLList<T>& listToIterate) : prev(0), cur(listToIterate.head), list(&listToIterate)
{

}

///////////////////////////////////////////////////////////////////////////////
// Function : begin
// Notes : moves the iterator to the head of the list
///////////////////////////////////////////////////////////////////////////////
template <typename T>
void SLLIter<T>::begin()
{
	prev = NULL;
	cur = this->list->head;
}

///////////////////////////////////////////////////////////////////////////////
// Function : end
// Notes : returns true if we are at the end of the list, false otherwise
///////////////////////////////////////////////////////////////////////////////
template <typename T>
bool SLLIter<T>::end() const
{
	return (cur == NULL);
}

///////////////////////////////////////////////////////////////////////////////
// Function : operator++
// Notes : move the iterator forward one node
///////////////////////////////////////////////////////////////////////////////
template <typename T>
SLLIter<T>& SLLIter<T>::operator++()
{
	if(cur != NULL)
	{
		prev = cur;
		cur = cur->next;
	}

	return *this;
}

///////////////////////////////////////////////////////////////////////////////
// Function : current
// Notes : returns the item at the current iterator location
///////////////////////////////////////////////////////////////////////////////
template <typename T>
T& SLLIter<T>::current() const
{

	//if(cur != NULL)
		return cur->data;


	//return *(new T());
}